package authentication.module;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import javax.security.auth.Subject;
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.NameCallback;
import javax.security.auth.callback.UnsupportedCallbackException;
import javax.security.auth.login.FailedLoginException;
import javax.security.auth.login.LoginException;
import javax.security.auth.spi.LoginModule;

public class SubjectLoginModule implements LoginModule {
	private CallbackHandler subjectCallbackHandler = null;
	private boolean subjectAuthenticationSuccessFlag = false;

	@Override
	public boolean abort() throws LoginException {
		return false;
	}

	@Override
	public boolean commit() throws LoginException {
		return subjectAuthenticationSuccessFlag;
	}

	@Override
	public void initialize(Subject arg0,
			CallbackHandler subjectCallbackHandler, Map<String, ?> arg2,
			Map<String, ?> arg3) {
		this.subjectCallbackHandler = subjectCallbackHandler;
	}

	@Override
	public boolean login() throws LoginException {
		// the app prompts the subject for his CNP so that he can be
		// authenticated
		Callback[] subjectCallbackArray = new Callback[1];
		subjectCallbackArray[0] = new NameCallback("Introduceti CNP: ");
		try {
			subjectCallbackHandler.handle(subjectCallbackArray);
		} catch (IOException | UnsupportedCallbackException e) {
			e.printStackTrace();
		}
		// the subject's input is stored in the "cnp" variable
		String cnp = ((NameCallback) subjectCallbackArray[0]).getName();
		// reading the stored subject CNPs from a file for a later comparison
		File file = new File(
				"C:/Users/Siji/workspace/PsiExam-Authentication/credentials/DB/subjectCNP.txt");
		try {
			List<String> cnpLineList = new ArrayList<String>();
			String cnpLine = null;
			FileInputStream fis = new FileInputStream(file);
			BufferedReader reader = new BufferedReader(new InputStreamReader(
					fis));
			// the CNP that are found in the file are inserted in an ArrayList
			while ((cnpLine = reader.readLine()) != null) {
				cnpLineList.add(cnpLine);
			}
			reader.close();
			// subject input is compared with each CNP line in the stored CNPs file
			for (int i = 0; i <= cnpLineList.size();) {
				String storedCnp = cnpLineList.get(i);
				if (cnp.equals(storedCnp)) {
					System.out
							.println("the authentication was a success!!! :)");
					subjectAuthenticationSuccessFlag = true;
					break;
				} else {
					i++;
					if (i == cnpLineList.size()) {
						subjectAuthenticationSuccessFlag = false;
						throw new FailedLoginException(
								"the authentication was a failure!!! :(");
					}
				}
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
		return subjectAuthenticationSuccessFlag;
	}

	@Override
	public boolean logout() throws LoginException {
		return false;
	}

}
